<?php
/**
 * Created by PhpStorm.
 * User: caoguangyang
 * Date: 2023-07-02
 * Time: 9:18
 */
namespace App\Services\Order;

use App\CodeResponse;
use App\Models\Goods\Goods;
use App\Models\Goods\GoodsProduct;
use App\Services\BaseServices;
use App\Models\Order\Cart;
use App\Services\Goods\GoodsServices;
use App\Services\Promotion\GrouponServices;

class CartServices extends BaseServices {

    public function getCartList($userId) {
        return Cart::query()->where('user_id', $userId)->get();
    }

//    public function getCheckedCartList($userId) {
//        return Cart::query()->where('user_id', $userId)->where('checked', 1)->get();
//    }
    public function getCheckedCarts($userId)
    {
        return Cart::query()->where('user_id', $userId)
            ->where('checked', 1)->get();
    }

    public function getValidCartList($userId) {
        // 获取购物车信息
        $list = $this->getCartList($userId);
        $goodsIds = $list->pluck('goods_id')->toArray();
        $goodsList = GoodsServices::getInstance()->getGoodsListByIds($goodsIds)->keyBy("id");

        // 获取已下架的商品id
        $invalidCartIds = [];
        $list = $list->filter(function (Cart $cart) use ($goodsList, &$invalidCartIds) {
            /** @var Goods $goods */
            $goods = $goodsList->get($cart->goods_id);
            $isValid = !empty($goods) && $goods->is_on_sale;
            if (!$isValid) {
                $invalidCartIds[] = $cart->id;
            }
            return $isValid;
        });

        // 删除购物车中下架的商品
        $this->deleteCartList($invalidCartIds);
        return $list;
    }

    public function deleteCartList($ids) {
        if (empty($ids)) {
            return 0;
        }
        return Cart::query()->whereIn('id', $ids)->delete();
    }

    public function getCartById($userId, $id) {
        return Cart::query()->where("user_id", $userId)
            ->where("id", $id)->first();
    }

    /**
     * 获取购物车信息
     * @param $userId
     * @param $goodsId
     * @param $productId
     * @return Cart|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getCartProduct($userId, $goodsId, $productId) {
        $res = Cart::query()->where('user_id', $userId)
            ->where('goods_id', $goodsId)
            ->where('product_id', $productId)
            ->first();
        return $res;
    }

    public function countCartProduct($userId) {
        return Cart::query()->where("user_id", $userId)->sum("number");
    }

    public function newCart($userId, Goods $goods, GoodsProduct $product, $number) {
        if ($number > $product->number) {
            return $this->throwBusinessException(CodeResponse::GOODS_NO_STOCK);
        }
        $cart = Cart::new();
        $cart->goods_sn = $goods->goods_sn;
        $cart->goods_name = $goods->name;
        $cart->pic_url = $product->url ?: $goods->pic_url;
        $cart->price = $product->price;
        $cart->specifications = $product->specifications;
        $cart->user_id = $userId;
        $cart->checked = true;
        $cart->number = $number;
        $cart->goods_id = $goods->id;
        $cart->product_id = $product->id;
        $cart->save();
        return $cart;
    }

    /**
     * 删除购物车数据
     * @param $userId
     * @param $productIds
     * @return bool|int|mixed|null
     * @throws \Exception
     */
    public function delete($userId, $productIds) {
        return Cart::query()->where("user_id", $userId)
            ->whereIn("product_id", $productIds)
            ->delete();
    }

    /**
     * @param $userId
     * @param $productIds
     * @param $isChecked
     */
    public function updateChecked($userId, $productIds, $isChecked) {
        return Cart::query()->where("user_id", $userId)
            ->whereIn("product_id", $productIds)
            ->update(["checked" => $isChecked]);
    }

    public function getGoodsInfo($goodsId, $productId) {
        $goods = GoodsServices::getInstance()->getGoods($goodsId);
        if (is_null($goods) || !$goods->is_on_sale) {
            $this->throwBusinessException(CodeResponse::GOODS_UNSHELVE);
        }

        $product = GoodsServices::getInstance()->getGoodsProductById($productId);
        if (is_null($product)) {
            $this->throwBusinessException(CodeResponse::GOODS_NO_STOCK);
        }
        return [$goods, $product];
    }

    /**
     * 添加购物车
     * @param $userId
     * @param $goodsId
     * @param $productId
     * @param $number
     */
    public function add($userId, $goodsId, $productId, $number) {
        list($goods, $product) = $this->getGoodsInfo($goodsId, $productId);
        $cartProduct = $this->getCartProduct($userId, $goodsId, $productId);
        if (is_null($cartProduct)) {
            $this->newCart($userId, $goods, $product, $number);
        } else {
            $number = $cartProduct->number + $number;
            $this->editCart($cartProduct, $product, $number);
        }
    }

    public function fastadd($userId, $goodsId, $productId, $number) {
        list($goods, $product) = $this->getGoodsInfo($goodsId, $productId);
        $cartProduct = $this->getCartProduct($userId, $goodsId, $productId);
        if (is_null($cartProduct)) {
            return $this->newCart($userId, $goods, $product, $number);
        } else {
            return $this->editCart($cartProduct, $product, $number);
        }
    }

    public function editCart($existCart, $product, $num) {
        if ($num > $product->number) {
            $this->throwBusinessException(CodeResponse::GOODS_NO_STOCK);
        }
        $existCart->number = $num;
        $existCart->save();
        return $existCart;
    }

    public function getCheckedCartList($userId, $cartId = null) {
        if (empty($cartId)) {
            $checkedGoodsList = $this->getcheckedCarts($userId);
        } else {
            $cart = $this->getCartById($userId, $cartId);
            if (empty($cart)) {
                $this->throwBadArgumentValue();
            }
            $checkedGoodsList = collect([$cart]);
        }
        return $checkedGoodsList;
    }

    /**
     * 计算商品总金额
     * @param $checkedGoodsList
     * @param $grouponRulesId
     * @param int $grouponPrice
     * @return int|string
     */
    public function getCartPriceCutGroupon($checkedGoodsList, $grouponRulesId, &$grouponPrice = 0)
    {
        $grouponRules = GrouponServices::getInstance()->getGrouponRulesById($grouponRulesId);
        $checkedGoodsPrice = 0;
        foreach ($checkedGoodsList as $cart) {
            if ($grouponRules && $grouponRules->goods_id == $cart->goods_id) {
                $grouponPrice = bcmul($grouponRules->discount, $cart->number, 2);
                $price = bcsub($cart->price, $grouponRules->discount, 2);
            } else {
                $price = $cart->price;
            }
            $price = bcmul($price, $cart->number, 2);
            $checkedGoodsPrice = bcadd($checkedGoodsPrice, $price, 2);
        }
        return $checkedGoodsPrice;
    }

    public function clearCartGoods($userId, $cartId = null) {
        if (empty($cartId)) {
            return Cart::query()->where("user_id", $userId)->where("checked", 1)->delete();
        }
        return Cart::query()->where('user_id', $userId)->where("id", $cartId)->deleted();
    }
}
